<?php

namespace app\admin\controller;

use app\common\model\Activity;
use app\common\model\VoteLog;
use app\common\model\Competitor as CompetitorModel;
use app\common\model\CompetitorData;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

class Competitor extends Base
{
    protected $model;

    protected function initialize()
    {
        parent::initialize();
        $this->model = CompetitorModel::getInstance();
        $this->config_model = CompetitorData::getInstance();
    }

    /*
     * 添加选手
     * */
    public function add()
    {
        //活动信息
        $activity_id = $this->request->param("activity_id");
        $activity_id = 11;
        //此处去查询详细的活动信息 暂时模拟

        $system = new \app\admin\controller\System();
        $config_array = $system->getConfig($this->admin_info);

        //最大上传图片、最少上传图片
        $rule['img']['max_image_num'] = 5;
        $rule['img']['min_image_num'] = 1;
        //如果为POST提交，写入数据
        if ($this->request->isPost()) {
            $com_array = $this->request->param("com") ?? [];
            $config_array = $this->request->param("config") ?? [];
            $post_data = $this->request->param() ?? [];
            //处理图片信息
            $key = 0;
            foreach ($post_data['image_url'] as $k => $v) {
                $trim = '';
                switch($post_data['image_type'][$k]){
                    case 0:
                        $trim = '/';
                        break;
                    case 1:
                        $trim = $config_array['oss_domain'];
                        break;
                    case 2:
                        $trim = $config_array['qiniu_domain'];
                        break;
                }
                if ($key == 0) {
                    $com_array['first_image'] = ltrim($v, $trim);
                    $com_array['first_image_type'] = $post_data['image_type'][$k];
                }
                $com_array['image'][$k]['url'] = ltrim($v, $trim);
                $com_array['image'][$k]['type'] = $post_data['image_type'][$k];
                $key++;
            }
            //组装数据
            $config_array['image'] = array2json($com_array['image']);
            $com_array['activity_id'] = $activity_id;
            $com_array['create_time'] = time();
            $com_array['update_time'] = time();
            //获取该选手编号
            $competitor_num = $this->model->getOne(['activity_id' => 11], ['order' => 'competitor_num desc', 'field' => 'competitor_num'])['competitor_num'] + 1;
            $com_array['competitor_num'] = $competitor_num;
            $com_rs = $this->model->addData($com_array);
            //写入主表成功 写附属表
            if ($com_rs) {
                $config_array['competitor_id'] = $com_rs;
                $config_rs = $this->config_model->addData($config_array);
                if ($config_rs) {
                    //附属表写入成功，跳转到选手列表
                    return $this->success("添加成功", url("admin/competitor/index"));
                } else {
                    //附属表写入失败，回滚
                    $this->model->delete($com_rs);
                    return $this->error("添加失败");
                }
            } else {
                return $this->error("添加失败");
            }
        }
        $this->assign("img_rule", $rule['img']);
        return $this->fetch();
    }


    /*
     * 选手管理
     * */
    public function index()
    {
        //查询活动信息
        //实例化model
        $vote_model = VoteLog::getInstance();

        //查询图片配置
        $configObj = new \app\admin\controller\System();
        $config_array = $configObj->getConfig($this->admin_info);

        //排序条件
        $config['order_type'] = $this->request->param("order_type") ?? "";
        $config['order_value'] = $this->request->param("order_value") ?? "";
        $order = '';
        if (!empty($config['order_type']) && !empty($config['order_value'])) {
            $order = $config['order_type'] . " " . $config['order_value'];
        }
        //查询字段
        $com_field = [
            'id', 'activity_id', 'competitor_num', 'name',
            'tel', 'first_image', 'first_image_type', 'is_audit',
            'day_ticket_num',
            'ticket_num',
            'ticket_num + fake_ticket_num as sum_ticket_num',
            'day_browse_num',
            'browse_num',
            'browse_num + fake_browse_num as sum_browse_num',
            'day_money_num',
            'money_num',
            'money_num + fake_money_num as sum_money_num',
            'is_lock', 'lock_time', 'is_vote', 'is_money', 'remark', 'create_time'
        ];
        //查询条件
        $config['is_audit'] = $this->request->param("is_audit") ?? -1;
        if ($config['is_audit'] == -1) {
            $com_where = ['isdelete' => 0, 'activity_id' => 11];
        } else {
            $com_where = ['isdelete' => 0, 'is_audit' => $config['is_audit'], 'activity_id' => 11];
        }
        //查询选手信息
        $com_array = $this->model
            ->where($com_where)
            ->field($com_field)
            ->order($order)
            ->paginate(11, false, ['query' => request()->param()]);
        //处理结果集
        foreach ($com_array as $k => $value) {
            //处理选手图片链接
            //图片域名
            $domain_name = '';
            switch ($value['first_image_type']) {
                case 1:
                    $domain_name = $config_array['oss_domain'];
                    break;
                case 2:
                    $domain_name = $config_array['qiniu_domain'];
                    break;
                default:
                    break;
            }
            $com_array[$k]['first_image'] = $domain_name . "/" . $value['first_image'];
        }
        $config['time'] = 30 * 60;
        $config['activity_id'] = 11;
        $this->assign("config", $config);
        $this->assign("com_array", $com_array);
        return $this->fetch();
    }

    /*
     * 修改选手配置 ：加票、加浏览量、加礼物金额
     * */
    public function incr()
    {
        $id = $this->request->param("id") ?? 0;
        $field = $this->request->param("field") ?? "";
        $value = $this->request->param("value") ?? "";
        if (empty($id) || empty($field) || empty($value)) {
            return 0;
        }
        //修改不同类型需进行不同处理
        //目前默认比例有问题 后期需要进行查询数据库
        switch ($field) {
            case 'ticket':
                $data = [
                    'fake_ticket_num' => (int)$value,
                    'fake_browse_num' => $value * 3
                ];
                break;
            case 'money':
                $field = 'fake_ticket_num';

                break;
            case 'browse':
                $data = [
                    'fake_browse_num' => (int)$value,
                ];
                break;
            default:
                break;
        }
        return $this->incrNum($id, $data);
    }

    /*
     * 修改选手配置 ：加票、加浏览量、加礼物金额
     * */
    public function incrNum($id, $data)
    {
        if (empty($id) || empty($data)) {
            return 0;
        }
        foreach ($data as $field => $value) {
            $rs = $this->model->where(["id" => $id])->setInc($field, $value);
        }
        return $rs;
    }

    /*
     * 修改选手配置
     * */
    public function editCompetitor()
    {
        $id = $this->request->param("id") ?? 0;
        $field = $this->request->param("field") ?? "";
        $value = $this->request->param("value") ?? "";
        if (empty($field) || (empty($value)) && $value != 0) {
            return 0;
        }

        //锁定需要重组数组
        if ($field == 'is_lock' && $value != 0) {
            $data['lock_time'] = time() + $value * 60;
            $data[$field] = 1;
        } else {
            $data = [$field => $value];
        }
        $rs = $this->model->editData($data, $id);
        return $rs;
    }

    /*
     * 设置今日之星
     * */
    public function setactivi()
    {
        $activi_id = $this->request->param("activi_id") ?? "";
        $competitor_id = $this->request->param("competitor_id") ?? "";
        if (empty($activi_id) || empty($competitor_id)) {
            return 0;
        }
        $activi_model = Activity::getInstance();
        $rs = $activi_model->editData(['competitor_id' => $competitor_id, 'update_time' => time()], $activi_id);
        return $rs;
    }


    /*
     * 批量修改
     * */
    public function editData()
    {
        $ids = $this->request->param("ids") ?? "";
        $field = $this->request->param("field") ?? "";
        $value = $this->request->param("value") ?? "";
        if (empty($ids) || empty($field) || empty($value)) {
            return false;
        }
        $ids = ltrim($ids, ",");
        $rs = $this->model->where('id', 'in', $ids)->update([$field => $value]);
        return $rs;
    }

    /*
     * 一键全局加票、加浏览量
     * */
    public function plusticket(){
        $min =  $this->request->param("min") ?? 1;
        $max =  $this->request->param("max") ?? 30;
        $type =  $this->request->param("type") ?? "ticket";
        $activity_id =  $this->request->param("activity_id") ?? 11;

        $data =  $this->model->where(['activity_id'=>$activity_id])->select();

        foreach ($data as $k => $val){
            if($type == 'ticket'){
                $rand = rand($min,$max);
                $rand2 =  $rand * 3;
                $data = ['fake_ticket_num'=>$rand  + $val['fake_ticket_num'],'fake_browse_num'=>$rand2 + $val['fake_browse_num']];
            }else{
                $rand = rand($min,$max);
                $data = ['fake_browse_num'=>$rand + $val['fake_browse_num']];
            }
            $rs = $this->model->editData($data,$val['id']);
        }
        return 1;
    }

    /*
     *  一键当页加票
     * */
    public function plusPageTicket(){
        $ids = $this->request->param("ids") ?? [];
        $ids = array_filter($ids);
        foreach ($ids as $id => $val) {
            $rs = $this->model->where(['id'=>$id])->setInc('fake_ticket_num',$val);
            $rs = $this->model->where(['id'=>$id])->setInc('fake_browse_num',$val * 3);
        }
        return 1;
    }



    /**
     * 导出excel表
     * $data：要导出excel表的数据，接受一个二维数组
     * $name：excel表的表名
     * $head：excel表的表头，接受一个一维数组
     * $key：$data中对应表头的键的数组，接受一个一维数组
     * 备注：此函数缺点是，表头（对应列数）不能超过26；
     *循环不够灵活，一个单元格中不方便存放两个数据库字段的值
     */
    public function outdata($name = '测试表', $data = [], $head = [], $keys = [], $option = [])
    {
        //计算表头数量
        $count = count($head);
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        if (isset($option['mergeCell'])) {
            //合并单元格
            $sheet->setMergeCells($option['mergeCell']);
            //设置合并后单元格内容
            $sheet->setCellValue('A1', $name);
            //设置居中
            $sheet->getStyleByColumnAndRow(1, 1)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
        }

        for ($i = 65; $i < $count + 65; $i++) {     //数字转字母从65开始，循环设置表头：
            $sheet->setCellValue(strtoupper(chr($i)) . '2', $head[$i - 65]);
            //设置居中
            $sheet->getStyleByColumnAndRow($i - 65, 2)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
        }

        /*--------------开始从数据库提取信息插入Excel表中------------------*/

        //循环设置单元格：
        foreach ($data as $key => $item) {
            //$key+2,因为第一行是表头，所以写到表格时   从第二行开始写
            for ($i = 65; $i < $count + 65; $i++) {
                //数字转字母从65开始：
                $sheet->setCellValue(strtoupper(chr($i)) . ($key + 3), $item[$keys[$i - 65]]);
                //设置居中
                $sheet->getStyleByColumnAndRow($i - 65, $key + 3)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER)->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
                //固定列宽
                $spreadsheet->getActiveSheet()->getColumnDimension(strtoupper(chr($i)))->setWidth(20);
            }
        }

        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="' . $name . '.xlsx"');
        header('Cache-Control: max-age=0');
        $writer = new Xlsx($spreadsheet);
        $writer->save('php://output');

        //删除清空：
        $spreadsheet->disconnectWorksheets();
        unset($spreadsheet);
        exit;
    }

    /*
     * 选手管理 导出排名专用
     * */
    public function exportExcel()
    {
        $activity_id = $this->request->param("activity_id") ?? "";
        if (empty($activity_id)) {
            return false;
        }
        //获取活动信息
        $activity_model = new \app\common\model\Activity();
        $name = $activity_model->getOne($activity_id, ['field' => 'title'])['title'];
        $data = $this->model
            ->field(['create_time', 'competitor_num', 'name', 'tel', 'first_image', 'remark', 'fake_ticket_num + ticket_num as sum_ticket_num', 'fake_money_num + money_num as sum_money_num'])
            ->order('sum_ticket_num desc')
            ->select();
        //排名
        foreach ($data as $k => &$value) {
            $value['order'] = $k + 1;
            $value['create_time'] = date("Y-m-d H:i:s", $value['create_time']);
        }

        $field = ['competitor_num', 'name', 'tel', 'first_image', 'sum_ticket_num', 'sum_money_num', 'create_time', 'order'];
        $title = ['编号', '姓名', '手机号码', '图片链接', '票数', '礼物', '参加时间', '排序/名次'];

        $count = count($title);
        $option['mergeCell'] = ['A1:' . strtoupper(chr(65 + $count - 1)) . '1' => 'A1:' . strtoupper(chr(65 + $count - 1)) . '1'];
        $this->outdata($name, $data, $title, $field, $option);
    }

    //批量导入 :Excel
    public function upFile()
    {
        $data = $this->importExecl(SITE_PATH . "uploads/1.xlsx", 0, 0);
        $temp = [];
        $field = $data[1];
        unset($data[1]);
        foreach ($data as $k => $val) {
            $temp2 = [];
            foreach ($val as $key=>$node){
                if(!empty($field[$key]) && !empty($node)){
                    $temp2[$field[$key]] = $node;
                }
            }
            $temp[]=$temp2;
//            $data[$k] = array_filter($val);
        }
        dump($temp);
        dump($data);
    }



    /**
     * 使用PHPEXECL导入
     *
     * @param string $file      文件地址
     * @param int    $sheet     工作表sheet(传0则获取第一个sheet)
     * @param int    $columnCnt 列数(传0则自动获取最大列)
     * @param array  $options   操作选项
     *                          array mergeCells 合并单元格数组
     *                          array formula    公式数组
     *                          array format     单元格格式数组
     *
     * @return array
     * @throws Exception
     */
    function importExecl(string $file = '', int $sheet = 0, int $columnCnt = 0, &$options = [])
    {
        try {
            /* 转码 */
            $file = iconv("utf-8", "gb2312", $file);

            if (empty($file) OR !file_exists($file)) {
                throw new \Exception('文件不存在!');
            }

            /** @var Xlsx $objRead */
            $objRead = IOFactory::createReader('Xlsx');

            if (!$objRead->canRead($file)) {
                /** @var Xls $objRead */
                $objRead = IOFactory::createReader('Xls');

                if (!$objRead->canRead($file)) {
                    throw new \Exception('只支持导入Excel文件！');
                }
            }

            /* 如果不需要获取特殊操作，则只读内容，可以大幅度提升读取Excel效率 */
            empty($options) && $objRead->setReadDataOnly(true);
            /* 建立excel对象 */
            $obj = $objRead->load($file);
            /* 获取指定的sheet表 */
            $currSheet = $obj->getSheet($sheet);

            if (isset($options['mergeCells'])) {
                /* 读取合并行列 */
                $options['mergeCells'] = $currSheet->getMergeCells();
            }

            if (0 == $columnCnt) {
                /* 取得最大的列号 */
                $columnH = $currSheet->getHighestColumn();
                /* 兼容原逻辑，循环时使用的是小于等于 */
                $columnCnt = Coordinate::columnIndexFromString($columnH);
            }

            /* 获取总行数 */
            $rowCnt = $currSheet->getHighestRow();
            $data   = [];

            /* 读取内容 */
            for ($_row = 1; $_row <= $rowCnt; $_row++) {
                $isNull = true;

                for ($_column = 1; $_column <= $columnCnt; $_column++) {
                    $cellName = Coordinate::stringFromColumnIndex($_column);
                    $cellId   = $cellName . $_row;
                    $cell     = $currSheet->getCell($cellId);

                    if (isset($options['format'])) {
                        /* 获取格式 */
                        $format = $cell->getStyle()->getNumberFormat()->getFormatCode();
                        /* 记录格式 */
                        $options['format'][$_row][$cellName] = $format;
                    }

                    if (isset($options['formula'])) {
                        /* 获取公式，公式均为=号开头数据 */
                        $formula = $currSheet->getCell($cellId)->getValue();

                        if (0 === strpos($formula, '=')) {
                            $options['formula'][$cellName . $_row] = $formula;
                        }
                    }

                    if (isset($format) && 'm/d/yyyy' == $format) {
                        /* 日期格式翻转处理 */
                        $cell->getStyle()->getNumberFormat()->setFormatCode('yyyy/mm/dd');
                    }

                    $data[$_row][$cellName] = trim($currSheet->getCell($cellId)->getFormattedValue());

                    if (!empty($data[$_row][$cellName])) {
                        $isNull = false;
                    }
                }

                /* 判断是否整行数据为空，是的话删除该行数据 */
                if ($isNull) {
                    unset($data[$_row]);
                }
            }

            return $data;
        } catch (\Exception $e) {
            throw $e;
        }
    }

    /**
     * 最火选手
     * @return mixed
     */
    public function hot()
    {
        return $this->fetch();
    }

}